<template>
  <!-- 多选框组，支持静态和远程选项加载 -->
  <a-checkbox-group v-bind="$attrs" v-model:value="innerValue" :options="finalOptions" :loading="loading" />
</template>

<script setup lang="ts">
import { ref, watch, onMounted, computed } from 'vue'

interface Props {
  value?: any // v-model 绑定值
  api?: (_params?: any) => Promise<any> // 可选远程加载函数（返回数组或对象）
  params?: Record<string, any> // 请求 API 的参数
  options?: any[] // 静态 options（优先于 api 结果）
  resultField?: string // API 返回对象时结果所在字段路径
  labelField?: string // 每个选项的 label 字段名，默认 'label'
  valueField?: string // 每个选项的 value 字段名，默认 'value'
  immediate?: boolean // 是否组件挂载后立即加载数据，默认 true
}

// 设置 props 默认值
const props = withDefaults(defineProps<Props>(), {
  options: () => [],
  immediate: true
})

// 定义 emits
const emit = defineEmits(['update:value'])

// 组件内部状态
const loading = ref(false) // 加载中标志
const innerValue = ref(props.value) // v-model 内部值
const dynamicOptions = ref<any[]>([]) // 动态加载的远程 options

// 计算最终 options 来源，优先使用静态 props.options
const finalOptions = computed(() => {
  return props.options?.length ? props.options : dynamicOptions.value
})

// 异步加载数据（如未提供静态 options 且有 api）
const fetchData = async () => {
  if (!props.api) return
  loading.value = true
  try {
    const res = await props.api(props.params)
    const list = props.resultField ? res[props.resultField] || [] : res
    dynamicOptions.value = Array.isArray(list)
      ? list.map((item: any) => ({
          label: item[props.labelField || 'label'],
          value: item[props.valueField || 'value']
        }))
      : []
  } catch (err) {
    console.error('ApiCheckbox fetch error:', err)
  } finally {
    loading.value = false
  }
}

// 同步外部 value 到内部
watch(
  () => props.value,
  (val) => (innerValue.value = val)
)

// 同步内部 value 到外部 v-model
watch(innerValue, (val) => emit('update:value', val))

// 若传入参数变化则重新拉取数据
watch(
  () => props.params,
  () => {
    fetchData()
  },
  { deep: true }
)

// 组件挂载时自动拉取数据（若无静态 options）
onMounted(() => {
  if (props.immediate !== false && !props.options?.length) {
    fetchData()
  }
})
</script>
